package com.nut.lmsc.interceptor;

import com.nut.lmsc.common.Constants;
import com.nut.lmsc.util.JacksonUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 请求参数，出参，方法耗时等日志统计
 */
@Aspect
@Component
@Slf4j
public class ApiLogAspect {

    public static final String EXPRESSION = "execution(public * com.nut.lmsc.api.admin.*.*(..)) || execution(public * com.nut.lmsc.api.client.*.*(..)) || execution(public * com.nut.lmsc.api.merchant.*.*(..)) || execution(public * com.nut.lmsc.api.sys.*.*(..))";

    /**
     * controller切入点
     */
    @Pointcut(EXPRESSION)
    public void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object doControllerAround(ProceedingJoinPoint jp) throws Throwable {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        long beginTime = System.currentTimeMillis();
        int random = ThreadLocalRandom.current().nextInt(9999) + 1000;
        StringBuilder sb = new StringBuilder(700);
        // 打印请求内容
        filled(sb, Constants.REQUEST_TOKEN, random, request.getHeader(Constants.LOGIN_TOKEN_KEY));
        filled(sb, Constants.REQUEST_IP, random, request.getRemoteAddr());
        filled(sb, Constants.REQUEST_URL, random, request.getRequestURL().toString());
        filled(sb, Constants.REQUEST_METHOD, random, jp.getSignature().toString());
        filled(sb, Constants.REQUEST_ARGS, random, Arrays.toString(jp.getArgs()));
        log.info(sb.toString());

        Object result = jp.proceed();
        long endTime = System.currentTimeMillis();

        // 取消二维码打印
        if (jp.getSignature().toString().contains("Qrcode")) {
            return result;
        }

        String content = JacksonUtils.toJson(result);
        int length = content.length();
        sb = new StringBuilder(length + 50);

//        if (content != null && length > 1500) {
//            filled(sb, Constants.REQUEST_METHOD, random, jp.getSignature().toString() + ",large_content=" + length);
//        } else {
        filled(sb, Constants.RESPONSE_TIME, random, (endTime - beginTime) + "");
        filled(sb, Constants.RESPONSE_CONTENT, random, content);
//        }

        log.info(sb.toString());
        return result;
    }

    private static void filled(StringBuilder sb, String key, int random, String val) {
        sb.append("\n").append(random).append("_").append(key).append("=").append(val);
    }

}
